package token

type Token int

const (
	Unknown Token = iota
	EndOfFile
	SingleLineCommentTrivia
	MultiLineCommentTrivia
	NewLineTrivia
	WhitespaceTrivia

	// We detect and preserve #! on the first line
	ShebangTrivia

	// We detect and provide better error recovery when we encounter a git merge marker.  This
	// allows us to edit files with git-conflict markers in them in a much more pleasant manner.
	ConflictMarkerTrivia

	// Literal
	CharLiteral
	IntLiteral
	LongLiteral
	FloatLiteral
	DoubleLiteral
	StringLiteral

	// Punctuation
	OpenBrace                         // {
	CloseBrace                        // }
	OpenParen                         // (
	CloseParen                        // )
	OpenBracket                       // [
	CloseBracket                      // ]
	Dot                               // .
	DotDotDot                         // ...
	Semicolon                         // ;
	Comma                             // ,
	LessThan                          // <
	GreaterThan                       // >
	LessThanEquals                    // <=
	GreaterThanEquals                 // >=
	EqualsEquals                      // ==
	ExclamationEquals                 // !=
	EqualsGreaterThan                 // ->
	Plus                              // +
	Minus                             // -
	Asterisk                          // *
	Slash                             // /
	Percent                           // %
	PlusPlus                          // ++
	MinusMinus                        // --
	LessThanLessThan                  // <
	GreaterThanGreaterThan            // >>
	GreaterThanGreaterThanGreaterThan // >>>
	Ampersand                         // &
	Bar                               // |
	Caret                             // ^
	Exclamation                       // !
	Tilde                             // ~
	AmpersandAmpersand                // &&
	BarBar                            // ||
	Question                          // ?
	Colon                             // :
	At                                // @
	Hash                              // #

	// Only doc dedicated
	Backtick                 // `
	BacktickBacktickBacktick // ```
	UnorderedListHead		 // '+ '
	OrderedListHead          // 'number. '
	AsteriskAsterisk         // **
	AsteriskAsteriskAsterisk // ***
	HashHash				 // ##
	HashHashHash		     // ###
	HashHashHashHash		 // ####
	HashHashHashHashHash	 // #####

	// Assignments
	Equals                                  // =
	PlusEquals                              // +=
	MinusEquals                             // -=
	AsteriskEquals                          // *=
	SlashEquals                             // /=
	PercentEquals                           // %=
	LessThanLessThanEquals                  // <<=
	GreaterThanGreaterThanEquals            // >>=
	GreaterThanGreaterThanGreaterThanEquals // >>>=
	AmpersandEquals                         // &=
	BarEquals                               // |=
	CaretEquals                             // ^=

	// Identifiers
	Identifier

	// Reserved words
	BreakKeyword
	CaseKeyword
	CatchKeyword
	ClassKeyword
	ConstKeyword
	ContinueKeyword
	DefaultKeyword
	DoKeyword
	ElseKeyword
	EnumKeyword
	ExtendsKeyword
	FalseKeyword
	FinallyKeyword
	ForKeyword
	FunctionKeyword
	IfKeyword
	ImportKeyword
	OfKeyword
	InstanceOfKeyword
	NewKeyword
	NullKeyword
	ReturnKeyword
	SuperKeyword
	SwitchKeyword
	ThisKeyword
	ThrowKeyword
	ThrowsKeyword
	TrueKeyword
	TryKeyword
	VarKeyword
	WhileKeyword
	ImplementsKeyword
	InterfaceKeyword
	AnnotationKeyword
	PackageKeyword
	PrivateKeyword
	ProtectedKeyword
	PublicKeyword
	StaticKeyword
	AbstractKeyword
	TransientKeyWord
	VolatileKeyWord
	SynchronizedKeyWord
	NativeKeyWord
	StrictfpKeyWord
	TransitiveKeyWord
	FinalKeyword
	AsKeyword
	VoidKeyword
	BooleanKeyword
	ConstructorKeyword
	ShortKeyword
	IntKeyword
	LongKeyword
	ByteKeyword
	CharKeyword
	FloatKeyword
	DoubleKeyword

	// Original keywords
	BreakKeywordOrg
	CaseKeywordOrg
	CatchKeywordOrg
	ClassKeywordOrg
	ConstKeywordOrg
	ContinueKeywordOrg
	DefaultKeywordOrg
	DoKeywordOrg
	ElseKeywordOrg
	EnumKeywordOrg
	ExtendsKeywordOrg
	FalseKeywordOrg
	FinallyKeywordOrg
	ForKeywordOrg
	IfKeywordOrg
	ImportKeywordOrg
	InstanceOfKeywordOrg
	NullKeywordOrg
	ReturnKeywordOrg
	SuperKeywordOrg
	SwitchKeywordOrg
	ThisKeywordOrg
	ThrowKeywordOrg
	ThrowsKeywordOrg
	TrueKeywordOrg
	TryKeywordOrg
	VarKeywordOrg
	VoidKeywordOrg
	WhileKeywordOrg
	NewKeywordOrg
	ImplementsKeywordOrg
	InterfaceKeywordOrg
	PackageKeywordOrg
	PrivateKeywordOrg
	ProtectedKeywordOrg
	PublicKeywordOrg
	StaticKeywordOrg
	AbstractKeywordOrg
	TransientKeyWordOrg
	VolatileKeyWordOrg
	SynchronizedKeyWordOrg
	NativeKeyWordOrg
	StrictfpKeyWordOrg
	TransitiveKeyWordOrg
	FinalKeywordOrg
	AsKeywordOrg
	BooleanKeywordOrg
	ConstructorKeywordOrg
	ShortKeywordOrg
	IntKeywordOrg
	LongKeywordOrg
	ByteKeywordOrg
	CharKeywordOrg
	FloatKeywordOrg
	DoubleKeywordOrg

	Count
	// Markers
	FirstAssignment          = Equals
	LastAssignment           = CaretEquals
	FirstCompoundAssignment  = PlusEquals
	LastCompoundAssignment 	 = CaretEquals
	FirstReservedWord        = BreakKeyword
	LastReservedWord         = WhileKeyword
	FirstKeyword             = BreakKeyword
	LastKeyword              = DoubleKeywordOrg
	FirstOriginalKeyword     = BreakKeywordOrg
	LastOriginalKeyword      = DoubleKeywordOrg
	FirstPunctuation         = OpenBrace
	LastPunctuation          = CaretEquals
	FirstTrivia              = SingleLineCommentTrivia
	LastTrivia               = ConflictMarkerTrivia
	FirstLiteral             = CharLiteral
	LastLiteral              = StringLiteral
	FirstBinaryOperator      = LessThan
	LastBinaryOperator       = CaretEquals
)

var tokens = [...]string{
	AbstractKeyword:                         "抽象",
	TransientKeyWord:                        "瞬态",
	VolatileKeyWord:                         "易变",
	SynchronizedKeyWord:                     "同步",
	NativeKeyWord:                           "本地",
	StrictfpKeyWord:                         "严格",
	TransitiveKeyWord:                       "传递",
	FinalKeyword:                            "终态",
	AsKeyword:                               "为",
	BooleanKeyword:                          "布尔",
	BreakKeyword:                            "跳出",
	CaseKeyword:                             "分支",
	CatchKeyword:                            "捕获",
	ClassKeyword:                            "类",
	ContinueKeyword:                         "继续",
	ConstKeyword:                            "常量",
	ConstructorKeyword:                      "构造",
	DefaultKeyword:                          "默认",
	DoKeyword:                               "重复",
	ElseKeyword:                             "否则",
	EnumKeyword:                             "枚举",
	ExtendsKeyword:                          "继承",
	FalseKeyword:                            "假",
	FinallyKeyword:                          "最后",
	ForKeyword:                              "遍历",
	FunctionKeyword:                         "方法",
	IfKeyword:                               "如果",
	ImplementsKeyword:                       "实现",
	ImportKeyword:                           "导入",
	OfKeyword:                               "于",
	InstanceOfKeyword:                       "实例于",
	InterfaceKeyword:                        "接口",
	AnnotationKeyword:                       "注解",
	NewKeyword:                              "创建",
	NullKeyword:                             "空",
	ShortKeyword:                            "短整数",
	IntKeyword:                              "整数",
	LongKeyword:                             "长整数",
	ByteKeyword:                             "字节",
	CharKeyword:                             "字符",
	FloatKeyword:                            "小数",
	DoubleKeyword:                           "长小数",
	PackageKeyword:                          "包",
	PrivateKeyword:                          "私有",
	ProtectedKeyword:                        "保护",
	PublicKeyword:                           "公有",
	ReturnKeyword:                           "返回",
	StaticKeyword:                           "静态",
	SuperKeyword:                            "基类",
	SwitchKeyword:                           "选择",
	ThisKeyword:                             "本对象",
	ThrowKeyword:                            "抛",
	ThrowsKeyword:                           "异常",
	TrueKeyword:                             "真",
	TryKeyword:                              "尝试",
	VarKeyword:                              "变量",
	VoidKeyword:                             "无",
	WhileKeyword:                            "循环",
	BreakKeywordOrg:                         "break",
	CaseKeywordOrg:                          "case",
	CatchKeywordOrg:                         "catch",
	ClassKeywordOrg:                         "class",
	ConstKeywordOrg:                         "const",
	ContinueKeywordOrg:                      "continue",
	DefaultKeywordOrg:                       "default",
	DoKeywordOrg:                            "do",
	ElseKeywordOrg:                          "else",
	EnumKeywordOrg:                          "enum",
	ExtendsKeywordOrg:                       "extends",
	FalseKeywordOrg:                         "false",
	FinallyKeywordOrg:                       "finally",
	ForKeywordOrg:                           "for",
	IfKeywordOrg:                            "if",
	ImportKeywordOrg:                        "import",
	InstanceOfKeywordOrg:                    "instanceof",
	NullKeywordOrg:                          "null",
	ReturnKeywordOrg:                        "return",
	SuperKeywordOrg:                         "super",
	SwitchKeywordOrg:                        "switch",
	ThisKeywordOrg:                          "this",
	ThrowKeywordOrg:                         "throw",
	ThrowsKeywordOrg:                        "throws",
	TrueKeywordOrg:                          "true",
	TryKeywordOrg:                           "try",
	VarKeywordOrg:                           "var",
	VoidKeywordOrg:                          "void",
	WhileKeywordOrg:                         "while",
	NewKeywordOrg:                           "new",
	ImplementsKeywordOrg:                    "implements",
	InterfaceKeywordOrg:                     "interface",
	PackageKeywordOrg:                       "package",
	PrivateKeywordOrg:                       "private",
	ProtectedKeywordOrg:                     "protected",
	PublicKeywordOrg:                        "public",
	StaticKeywordOrg:                        "static",
	AbstractKeywordOrg:                      "abstract",
	TransientKeyWordOrg:                     "transient",
	VolatileKeyWordOrg:                      "volatile",
	SynchronizedKeyWordOrg:                  "synchronized",
	NativeKeyWordOrg:                        "native",
	StrictfpKeyWordOrg:                      "strictfp",
	TransitiveKeyWordOrg:                    "transitive",
	FinalKeywordOrg:                         "final",
	AsKeywordOrg:                            "as",
	BooleanKeywordOrg:                       "boolean",
	ConstructorKeywordOrg:                   "constructor",
	ShortKeywordOrg:                         "short",
	IntKeywordOrg:                           "int",
	LongKeywordOrg:                          "long",
	ByteKeywordOrg:                          "byte",
	CharKeywordOrg:                          "char",
	FloatKeywordOrg:                         "float",
	DoubleKeywordOrg:                        "double",
	OpenBrace:                               "{",
	CloseBrace:                              "}",
	OpenParen:                               "(",
	CloseParen:                              ")",
	OpenBracket:                             "[",
	CloseBracket:                            "]",
	Dot:                                     ".",
	DotDotDot:                               "...",
	Semicolon:                               ";",
	Comma:                                   ",",
	LessThan:                                "<",
	GreaterThan:                             ">",
	LessThanEquals:                          "<=",
	GreaterThanEquals:                       ">=",
	EqualsEquals:                            "==",
	ExclamationEquals:                       "!=",
	EqualsGreaterThan:                       "=>",
	Plus:                                    "+",
	Minus:                                   "-",
	Asterisk:                                "*",
	Slash:                                   "/",
	Percent:                                 "%",
	PlusPlus:                                "++",
	MinusMinus:                              "--",
	LessThanLessThan:                        "<<",
	GreaterThanGreaterThan:                  ">>",
	GreaterThanGreaterThanGreaterThan:       ">>>",
	Ampersand:                               "&",
	Bar:                                     "|",
	Caret:                                   "^",
	Exclamation:                             "!",
	Tilde:                                   "~",
	AmpersandAmpersand:                      "&&",
	BarBar:                                  "||",
	Question:                                "?",
	Colon:                                   ":",
	Equals:                                  "=",
	PlusEquals:                              "+=",
	MinusEquals:                             "-=",
	AsteriskEquals:                          "*=",
	SlashEquals:                             "/=",
	PercentEquals:                           "%=",
	LessThanLessThanEquals:                  "<<=",
	GreaterThanGreaterThanEquals:            ">>=",
	GreaterThanGreaterThanGreaterThanEquals: ">>>=",
	AmpersandEquals:                         "&=",
	BarEquals:                               "|=",
	CaretEquals:                             "^=",
	At:                                      "@",
	Hash:                                    "#",
	HashHash:                                "##",
	HashHashHash:                            "###",
	HashHashHashHash:                        "####",
	HashHashHashHashHash:                    "#####",
}

func (tok Token) IsAssignmentOperator() bool 	{ return tok >= FirstAssignment && tok <= LastAssignment }
func (tok Token) IsCompoundAssignment() bool 	{ return tok >= FirstCompoundAssignment && tok <= LastCompoundAssignment }
func (tok Token) IsReservedWord() bool 			{ return tok >= FirstReservedWord && tok <= LastReservedWord }
func (tok Token) IsKeyword() bool 				{ return tok >= FirstKeyword && tok <= LastKeyword }
func (tok Token) IsOriginalKeyword() bool 		{ return tok >= FirstOriginalKeyword && tok <= LastOriginalKeyword}
func (tok Token) IsPunctuation () bool { return tok >= FirstPunctuation && tok <= LastPunctuation }
func (tok Token) IsTrivia() bool       { return tok >= FirstTrivia && tok <= LastTrivia }
func (tok Token) IsLiteral() bool      { return tok >= FirstLiteral && tok <= LastLiteral }
func (tok Token) IsBinaryOperator() bool 		{ return tok >= FirstBinaryOperator && tok <= LastBinaryOperator}
func (tok Token) IsModifier() bool {
	switch tok {
	case AbstractKeyword,
		ConstKeyword,
		DefaultKeyword,
		PublicKeyword,
		PrivateKeyword,
		ProtectedKeyword,
		StaticKeyword,
		TransientKeyWord,
		VolatileKeyWord,
		SynchronizedKeyWord,
		NativeKeyWord,
		StrictfpKeyWord,
		TransitiveKeyWord,
		FinalKeyword:
		return true
	}
	return false
}
func (tok Token) IsAccessibilityModifier() bool {
	switch tok {
	case PublicKeyword,
		PrivateKeyword,
		ProtectedKeyword:
		return true
	}
	return false
}
func (tok Token) ToOriginal() Token {
	switch tok {
	case BreakKeyword:
		return BreakKeywordOrg
	case CaseKeyword:
		return CaseKeywordOrg
	case CatchKeyword:
		return CatchKeywordOrg
	case ClassKeyword:
		return ClassKeywordOrg
	case ConstKeyword:
		return ConstKeywordOrg
	case ContinueKeyword:
		return ContinueKeywordOrg
	case DefaultKeyword:
		return DefaultKeywordOrg
	case DoKeyword:
		return DoKeywordOrg
	case ElseKeyword:
		return ElseKeywordOrg
	case EnumKeyword:
		return EnumKeywordOrg
	case ExtendsKeyword:
		return ExtendsKeywordOrg
	case FalseKeyword:
		return FalseKeywordOrg
	case FinallyKeyword:
		return FinallyKeywordOrg
	case ForKeyword:
		return ForKeywordOrg
	case IfKeyword:
		return IfKeywordOrg
	case ImportKeyword:
		return ImportKeywordOrg
	case InstanceOfKeyword:
		return InstanceOfKeywordOrg
	case NullKeyword:
		return NullKeywordOrg
	case ReturnKeyword:
		return ReturnKeywordOrg
	case SuperKeyword:
		return SuperKeywordOrg
	case SwitchKeyword:
		return SwitchKeywordOrg
	case ThisKeyword:
		return ThisKeywordOrg
	case ThrowKeyword:
		return ThrowKeywordOrg
	case ThrowsKeyword:
		return ThrowsKeywordOrg
	case TrueKeyword:
		return TrueKeywordOrg
	case TryKeyword:
		return TryKeywordOrg
	case VarKeyword:
		return VarKeywordOrg
	case VoidKeyword:
		return VoidKeywordOrg
	case WhileKeyword:
		return WhileKeywordOrg
	case NewKeyword:
		return NewKeywordOrg
	case ImplementsKeyword:
		return ImplementsKeywordOrg
	case InterfaceKeyword:
		return InterfaceKeywordOrg
	case PackageKeyword:
		return PackageKeywordOrg
	case PrivateKeyword:
		return PrivateKeywordOrg
	case ProtectedKeyword:
		return ProtectedKeywordOrg
	case PublicKeyword:
		return PublicKeywordOrg
	case StaticKeyword:
		return StaticKeywordOrg
	case AbstractKeyword:
		return AbstractKeywordOrg
	case FinalKeyword:
		return FinalKeywordOrg
	case AsKeyword:
		return AsKeywordOrg
	case BooleanKeyword:
		return BooleanKeywordOrg
	case ConstructorKeyword:
		return ConstructorKeywordOrg
	case ShortKeyword:
		return ShortKeywordOrg
	case IntKeyword:
		return IntKeywordOrg
	case LongKeyword:
		return LongKeywordOrg
	case ByteKeyword:
		return ByteKeywordOrg
	case CharKeyword:
		return CharKeywordOrg
	case FloatKeyword:
		return FloatKeywordOrg
	case DoubleKeyword:
		return DoubleKeywordOrg
	default:
		return tok
	}
}

func (tok Token) ToString() string			    { return tokens[tok] }

var keywords map[string]Token
func init() {
	keywords = make(map[string]Token)
	for i := FirstKeyword; i <= LastKeyword; i++ {
		keywords[tokens[i]] = i
	}
}

func KeywordFromString(text string) Token {
	tok, ok := keywords[text]
	if ok {
		return tok
	}
	return Unknown
}


